/*
 * customer_test.c
 *
 *  Created on: 23/04/2011
 *      Author: Yotam and Gilad
 */

#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include "test_utilities.h"
#include "../list.h"
#include "../customer.h"
#include "../bill.h"
#include "../car.h"

#define ZERO 0

bool testCopyCustomer() {
	Customer customer1 = NULL;
	Customer customer2 = customerCreate(76543, "Meirav");
	ASSERT_TEST(copyCustomer(customer1) == NULL);
	Customer customer2Copy = copyCustomer(customer2);
	ASSERT_TEST(strcmp(customerGetName(customer2Copy),"Meirav") == ZERO);
	ASSERT_TEST(customerGetId(customer2Copy) == 76543);
	ASSERT_TEST(customerGetFee(customer2Copy) == 0);
	freeCustomer(customer1);
	freeCustomer(customer2);
	freeCustomer(customer2Copy);
	return true;
}

bool testFreeCustomer() {
	Customer customer1 = customerCreate(123123, "Noa");
	Customer customer2 = NULL;
	freeCustomer(customer1);
	freeCustomer(customer2);
	/*	tested via valgrind    */
	return true;
}

bool testCompareCustomerId() {
	Customer customer1 = customerCreate(456456, "Neta");
	Customer customer2 = customerCreate(123123, "Maya");
	ASSERT_TEST(compareCustomerId(customer1,customer2) > ZERO);
	freeCustomer(customer1);
	freeCustomer(customer2);
	return true;
}

bool testCompareCustomerFee() {
	Customer customer1 = customerCreate(456456, "Neta");
	Customer customer2 = customerCreate(123123, "Maya");
	ASSERT_TEST(compareCustomerFee(customer1,customer2) == ZERO);
	Car car = carCreate(876543, "Volvo", 2000, 34);
	customerRentCar(customer2, car);
	customerReturnCar(customer2, 876543, 20);
	ASSERT_TEST(compareCustomerFee(customer1,customer2) > ZERO);
	carFree(car);
	freeCustomer(customer1);
	freeCustomer(customer2);
	return true;
}

bool testCustomerFilterOutNoFee() {
	Customer customer1 = customerCreate(1245, "Nimrod");
	Customer customer2 = customerCreate(9875, "Michal");
	Car car = carCreate(654987, "Cadilac", 5678, 95);
	ASSERT_TEST(customerFilterOutNoFee(customer1) == false);
	customerRentCar(customer2, car);
	customerReturnCar(customer2, 654987, 10);
	ASSERT_TEST(customerFilterOutNoFee(customer2) == true);
	carFree(car);
	freeCustomer(customer1);
	freeCustomer(customer2);
	return true;
}

bool testCustomerCreate() {
	Customer customer = customerCreate(345203, "Yotam");
	ASSERT_TEST(customerGetId(customer) == 345203);
	ASSERT_TEST(strcmp(customerGetName(customer),"Yotam") == ZERO);
	freeCustomer(customer);
	return true;
}

bool testCustomerRentCar() {
	Customer customer1 = NULL;
	Customer customer2 = customerCreate(487642, "Gilaad");
	Customer customer3 = customerCreate(555432, "Ben");
	Car car1 = NULL;
	Car car2 = carCreate(2827565, "Mazda", 1882, 13);
	ASSERT_TEST(customerRentCar(customer1,car2) == CUSTOMER_NULL_ARGUMENT);
	ASSERT_TEST(customerRentCar(customer2,car1) == CUSTOMER_NULL_ARGUMENT);
	ASSERT_TEST(customerRentCar(customer3,car2) == CUSTOMER_SUCCESS);
	carFree(car1);
	carFree(car2);
	freeCustomer(customer1);
	freeCustomer(customer2);
	freeCustomer(customer3);
	return true;
}

bool testCustomerReturnCar() {
	Customer customer1 = NULL;
	Customer customer2 = customerCreate(45678, "Amir");
	Car car1 = NULL;
	Car car2 = carCreate(909090, "BMW", 1000, 30);
	customerRentCar(customer2, car2);
	ASSERT_TEST(customerReturnCar(customer1,909090,20) ==
			CUSTOMER_NULL_ARGUMENT);
	ASSERT_TEST(customerReturnCar(customer2,909091,20) ==
			CUSTOMER_CAR_NOT_RENTED);
	ASSERT_TEST(customerReturnCar(customer2,909090,20) == CUSTOMER_SUCCESS);
	carFree(car1);
	carFree(car2);
	freeCustomer(customer1);
	freeCustomer(customer2);
	return true;
}

bool testCustomerGetName() {
	Customer customer = customerCreate(997442, "Guy");
	ASSERT_TEST(strcmp(customerGetName(customer),"Guy") == ZERO);
	freeCustomer(customer);
	return true;
}

bool testCustomerGetId() {
	Customer customer = customerCreate(1118899, "Ben");
	ASSERT_TEST(customerGetId(customer) == 1118899);
	freeCustomer(customer);
	return true;
}

bool testCustomerGetFee() {
	Customer customer = customerCreate(333789, "Yotam");
	Car car = carCreate(88888, "Toyota", 100, 13);
	customerRentCar(customer, car);
	customerReturnCar(customer, 88888, 10);
	ASSERT_TEST(customerGetFee(customer) == 1000);
	carFree(car);
	freeCustomer(customer);
	return true;
}

bool testCustomerGetPastPayment() {
	Customer customer = customerCreate(273847, "Avi");
	Car car = carCreate(828282, "Chevrolet", 10, 5);
	customerRentCar(customer, car);
	customerReturnCar(customer, 828282, 10);
	customerPayBill(customer);
	ASSERT_TEST(customerGetPastPayment(customer) == 100);
	ASSERT_TEST(customerGetFee(customer) == 0);
	carFree(car);
	freeCustomer(customer);
	return true;
}

bool testCustomerGetBillList() {
	Customer customer1 = NULL;
	Customer customer2 = customerCreate(754746, "Gal");
	Car car1 = carCreate(11111, "Infinity", 1000, 145);
	Car car2 = carCreate(22222, "Honda", 780, 190);
	ASSERT_TEST(customerGetBillList(customer1) == NULL);
	customerRentCar(customer2, car1);
	customerRentCar(customer2, car2);
	customerReturnCar(customer2, 11111, 100);
	customerReturnCar(customer2, 22222, 200);
	List billList = customerGetBillList(customer2);
	ASSERT_TEST(listGetSize(billList) == 2);
	ASSERT_TEST(strcmp(billGetCarName(listGetFirst(billList)),
															"Infinity") == 0);
	ASSERT_TEST(billGetCarLicense(listGetCurrent(billList)) == 11111);
	ASSERT_TEST(strcmp(billGetCarName(listGetNext(billList)), "Honda") == 0);
	ASSERT_TEST(billGetCarLicense(listGetCurrent(billList)) == 22222);
	listDestroy(billList);
	carFree(car1);
	carFree(car2);
	freeCustomer(customer1);
	freeCustomer(customer2);
	return true;
}

bool testCustomerGetRentedCarsList() {
	Customer customer1 = NULL;
	Customer customer2 = customerCreate(951951, "Yotam");
	Car car1 = carCreate(33333, "Suzuky", 340, 76);
	Car car2 = carCreate(44444, "Mazda", 946, 104);
	ASSERT_TEST(customerGetRentedCarsList(customer1) == NULL);
	customerRentCar(customer2, car1);
	customerRentCar(customer2, car2);
	List rentedCarList = customerGetRentedCarsList(customer2);

	ASSERT_TEST(listGetSize(rentedCarList) == 2);
	ASSERT_TEST(strcmp(carGetName(listGetFirst(rentedCarList)), "Suzuky") == 0);
	ASSERT_TEST(carGetLicensePlate(listGetCurrent(rentedCarList)) == 33333);
	ASSERT_TEST(strcmp(carGetName(listGetNext(rentedCarList)), "Mazda") == 0);
	ASSERT_TEST(carGetLicensePlate(listGetCurrent(rentedCarList)) == 44444);

	customerReturnCar(customer2, 33333, 100);
	customerReturnCar(customer2, 44444, 200);
	listDestroy(rentedCarList);

	rentedCarList = customerGetRentedCarsList(customer2);
	ASSERT_TEST(listGetSize(rentedCarList) == 0);
	listDestroy(rentedCarList);

	carFree(car1);
	carFree(car2);
	freeCustomer(customer1);
	freeCustomer(customer2);
	return true;
}

bool testCustomerGetNumberOfRentedCars() {
	Customer customer = customerCreate(34566, "Argaman");
	Car car1 = carCreate(56565, "Honda", 120, 230);
	customerRentCar(customer, car1);
	customerReturnCar(customer, 56565, 15);
	ASSERT_TEST(customerGetNumberOfCarsInBill(customer) == 1);
	carFree(car1);
	freeCustomer(customer);
	return true;
}

bool testCustomerGetNumberOfCarsInBill() {
	Customer customer = customerCreate(12345, "Lior");
	Car car1 = carCreate(56565, "Honda", 130, 256);
	Car car2 = carCreate(89898, "Jaguar", 450, 10);
	customerRentCar(customer, car1);
	customerRentCar(customer, car2);
	customerReturnCar(customer, 56565, 75);
	customerReturnCar(customer, 89898, 25);
	ASSERT_TEST(customerGetNumberOfCarsInBill(customer) == 2);
	customerPayBill(customer);
	customerRentCar(customer, car1);
	customerReturnCar(customer, 56565, 20);
	customerRentCar(customer, car1);
	customerReturnCar(customer, 56565, 20);
	ASSERT_TEST(customerGetNumberOfCarsInBill(customer) == 2);

	carFree(car1);
	carFree(car2);
	freeCustomer(customer);
	return true;
}

bool testCustomerPayBill() {
	Customer customer1 = NULL;
	Customer customer2 = customerCreate(273847, "Avi");
	Car car = carCreate(12345, "Chevrolet", 15, 5);
	customerRentCar(customer2, car);
	customerReturnCar(customer2, 12345, 10);
	customerPayBill(customer2);
	ASSERT_TEST(customerPayBill(customer1) == CUSTOMER_NULL_ARGUMENT);
	ASSERT_TEST(customerGetPastPayment(customer2) == 150);
	ASSERT_TEST(customerGetFee(customer2) == 0);
	carFree(car);
	freeCustomer(customer1);
	freeCustomer(customer2);
	return true;
}

int main() {
	RUN_TEST(testCopyCustomer);
	RUN_TEST(testFreeCustomer);
	RUN_TEST(testCompareCustomerId);
	RUN_TEST(testCompareCustomerFee);
	RUN_TEST(testCustomerFilterOutNoFee);
	RUN_TEST(testCustomerCreate);
	RUN_TEST(testCustomerRentCar);
	RUN_TEST(testCustomerReturnCar);
	RUN_TEST(testCustomerGetName);
	RUN_TEST(testCustomerGetId);
	RUN_TEST(testCustomerGetFee);
	RUN_TEST(testCustomerGetPastPayment);
	RUN_TEST(testCustomerGetBillList);
	RUN_TEST(testCustomerGetRentedCarsList);
	RUN_TEST(testCustomerGetNumberOfRentedCars);
	RUN_TEST(testCustomerGetNumberOfCarsInBill);
	RUN_TEST(testCustomerPayBill);
	return 0;
}
